
from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def read_root():
    return {"Hello": "World"}

@app.get("/items/{item_id}")
def read_item(item_id: int, q: str = None):
    return {"item_id": item_id, "q": f"接口id：{item_id}","q_context":f"q= {q}"}

"""
1. **路由与子应用（Mounting Sub-Applications）**:

- 使用`Mount`将子应用挂载到主应用，实现模块化。

- 示例：挂载一个静态文件应用和一个子应用（如FastAPI应用或其他Starlette应用）。

2. **中间件（Middleware）**:

- 添加常用中间件，如`CORSMiddleware`、`GZipMiddleware`等。

- 自定义中间件：例如记录请求时间、处理异常等。

3. **后台任务（Background Tasks）**:

- 在响应返回后执行后台任务，如发送邮件、清理资源等。

4. **依赖注入（Dependency Injection）**:

- Starlette本身不提供依赖注入，但可以结合第三方库（如`dependencies`）或通过请求状态（`request.state`）实现。

5. **测试（Testing）**:

- 使用`TestClient`进行测试，模拟请求并检查响应。

6. **WebSocket 高级用法**:

- 处理WebSocket连接，实现实时通信，包括接收和发送消息，管理连接池。

7. **事件处理（Lifespan Events）**:

- 使用`lifespan`事件处理应用启动和关闭时的逻辑，如连接数据库、释放资源。

8. **自定义响应（Custom Responses）**:

- 返回各种响应类型，如`JSONResponse`、`HTMLResponse`、`StreamingResponse`等，并自定义响应头、状态码。

9. **请求状态（Request State）**:

- 使用`request.state`在请求生命周期内存储和传递数据（如数据库连接）。

10. **文件处理（File Responses and Uploads）**:

- 处理文件上传（`request.form()`获取表单数据，包含文件）和发送文件（`FileResponse`）。

11. **路由中间件（Router-specific Middleware）**:

- 为特定路由应用中间件，例如对某个子路由进行认证。

12. **模板渲染（Template Rendering）**:

- 使用Jinja2等模板引擎渲染HTML。
"""





# # 自定义中间件（高级）处理请求/响应生命周期，添加全局逻辑（如日志、鉴权）：
# # 中间件顺序：中间件按添加顺序反向执行（最后一个中间件最先处理请求）。
# from starlette.middleware.base import BaseHTTPMiddleware

# class CustomHeaderMiddleware(BaseHTTPMiddleware):
#     async def dispatch(self, request, call_next):
#         # 请求处理前
#         if "admin" not in request.url.path:
#             return JSONResponse({"error": "Forbidden"}, status_code=403)
        
#         response = await call_next(request)
#         # 响应处理后
#         response.headers["X-Custom-Header"] = "Processed"
#         return response

# app.add_middleware(CustomHeaderMiddleware)




# # 依赖注入系统（常见）复用数据库连接等资源：
# from starlette.requests import Request
# def get_db(request: Request):
#     return request.app.state.db  # 从应用状态获取连接池

# @app.route("/users")
# async def get_users(request):
#     db = get_db(request)
#     users = await db.fetch("SELECT * FROM users")
#     return JSONResponse(users)




# # 后台任务（高级）响应返回后执行异步任务（如发送邮件）：
# from starlette.background import BackgroundTask
# from starlette.responses import JSONResponse
# async def send_notification(email: str):
#     await email_service.send(email, "Update Received")

# @app.post("/webhook")
# async def webhook_receiver(request):
#     data = await request.json()
#     task = BackgroundTask(send_notification, email=data["email"])
#     return JSONResponse({"status": "accepted"}, background=task)





# # 子应用挂载（模块化设计）分离路由到独立应用：
# from starlette.routing import Mount,Router
# from starlette.staticfiles import StaticFiles


# admin_app = Router()

# @admin_app.route("/dashboard")
# async def admin_dashboard(request):
#     ...

# app = Router(routes=[
#     Mount("/admin", app=admin_app),
#     Mount("/static", app=StaticFiles(directory="static")),
# ])





# # WebSocket 广播（高级实时通信）管理多个 WebSocket 连接：
# from starlette.websockets import WebSocket

# active_connections = []

# @app.websocket("/ws")
# async def websocket_endpoint(websocket: WebSocket):
#     await websocket.accept()
#     active_connections.append(websocket)
#     try:
#         while True:
#             data = await websocket.receive_text()
#             # 广播消息给所有连接
#             for conn in active_connections:
#                 await conn.send_text(f"Broadcast: {data}")
#     finally:
#         active_connections.remove(websocket)




# # 请求状态管理（常见）在中间件中传递数据：
# # 状态管理： request.state 是存储请求级数据的推荐方式（非线程安全，但 Starlette 是异步框架）。
# @app.middleware("http")
# async def auth_middleware(request, call_next):
#     token = request.headers.get("Authorization")
#     user = await auth_service.verify_token(token)
#     request.state.user = user  # 存储到请求状态
#     return await call_next(request)

# @app.get("/profile")
# async def user_profile(request):
#     user = request.state.user  # 从状态获取
#     return JSONResponse({"name": user.name})






# 响应序列化控制（高级）自定义 JSON 响应格式：
# from starlette.responses import JSONResponse

# class CamelCaseJSONResponse(JSONResponse):
#     def render(self, content) -> bytes:
#         # 将 snake_case 字段转为 camelCase
#         content = convert_keys(content, camelize)
#         return super().render(content)

# @app.get("/data", response_class=CamelCaseJSONResponse)
# async def get_data():
#     return {"user_id": 1, "full_name": "Alice Smith"}







# # 测试客户端（常见）使用 TestClient 编写单元测试：
# from fastapi import FastAPI
# app = FastAPI()
# @app.get("/")
# def read_root():
#     return {"Hello": "World"}

# @app.get("/items/{item_id}")
# def read_item(item_id: int, q: str = None):
#     return {"item_id": item_id, "q": f"接口id：{item_id}","q_context":f"q= {q}"}

# # 测试客户端（常见）使用 TestClient 编写单元测试：
# from starlette.testclient import TestClient

# def test_user_endpoint():
#     client = TestClient(app)
#     response = client.get("/items/1")
#     # response = client.get("/items/1?q=2")
#     # response = client.get("/items/10")
#     assert response.status_code == 200
#     assert response.json()["item_id"] == 1


# if __name__ == "__main__":
#     test_user_endpoint()








# # 生命周期事件（高级）启动/关闭资源管理：
# # 资源清理：使用 lifespan 或 BackgroundTask 确保资源（如数据库连接）正确释放
# from contextlib import asynccontextmanager

# @asynccontextmanager
# async def lifespan(app):
#     app.state.redis = await redis.connect()  # 启动时
#     yield
#     await app.state.redis.close()  # 关闭时

# app = Starlette(lifespan=lifespan)







# # 流式响应（大文件处理）高效处理大文件下载：
# # 性能：StreamingResponse 和 FileResponse 可减少内存占用
# from starlette.responses import StreamingResponse

# @app.get("/large-file")
# async def large_file():
#     def file_iterator():
#         with open("bigdata.bin", "rb") as f:
#             while chunk := f.read(64 * 1024):  # 64KB 分块
#                 yield chunk
#     return StreamingResponse(file_iterator(), media_type="application/octet-stream")






if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="127.0.0.1", port=8000)
    